home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_ghostscript.idb / usr / freeware / lib / ghostscript / 3.33 / wrfont.ps.z / wrfont.ps
Encoding:
Text File  |  1998-05-21  |  17.4 KB  |  658 lines

  1. %    Copyright (C) 1991, 1995 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of GNU Ghostscript.
  3. % GNU Ghostscript is distributed in the hope that it will be useful, but
  4. % WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility to
  5. % anyone for the consequences of using it or for whether it serves any
  6. % particular purpose or works at all, unless he says so in writing.  Refer
  7. % to the GNU Ghostscript General Public License for full details.
  8.  
  9. % wrfont.ps
  10. % Write out a Type 1 font in readable, reloadable form.
  11. % Note that this does NOT work on protected fonts, such as Adobe fonts
  12. % (unless you have loaded unprot.ps first, in which case you may be
  13. % violating the Adobe license).
  14.  
  15. % ****** NOTE: This file must be kept consistent with gs_pfile.ps.
  16.  
  17. /wrfont_dict 100 dict def
  18. wrfont_dict begin
  19.  
  20. % ------ Options ------ %
  21.  
  22. % Define whether to use eexec encryption for the font.
  23. % eexec encryption is only useful for compatibility with Adobe Type Manager
  24. % and other programs; it only slows Ghostscript down.
  25.    /eexec_encrypt false def
  26.  
  27. % Define whether to write out the CharStrings in binary or in hex.
  28. % Binary takes less space on the file, but isn't guaranteed portable.
  29.    /binary_CharStrings false def
  30.  
  31. % Define whether to use binary token encodings when possible.
  32. % Binary tokens are smaller and load faster, but are a Level 2 feature.
  33.    /binary_tokens false def
  34.  
  35. % Define whether to encrypt the CharStrings on the file.  (CharStrings
  36. % are always encrypted in memory.)  Unencrypted CharStrings load about
  37. % 20% slower, but make the files compress much better for transport.
  38.    /encrypt_CharStrings true def
  39.  
  40. % Define whether the font must provide standard PostScript language
  41. % equivalents for any facilities it uses that are provided in Ghostscript
  42. % but are not part of the standard PostScript language.
  43.    /standard_only true def
  44.  
  45. % Define the value of lenIV to use in writing out the font.
  46. % use_lenIV = 0 produces the smallest output, but this may not be
  47. % compatible with old Adobe interpreters.  use_lenIV = -1 means
  48. % use the value of lenIV from the font.
  49.    /use_lenIV -1 def
  50.  
  51. % Define whether to produce the smallest possible output, relying
  52. % as much as possible on Ghostscript-specific support code.
  53. % Taking full advantage of this requires the following settings:
  54. % binary_CharStrings = true, binary_tokens = true, standard_only = false.
  55.    /smallest_output false def
  56.  
  57. % Define whether to write out all currently known Encodings by name,
  58. % or only StandardEncoding and ISOLatin1Encoding.
  59.    /name_all_Encodings false def
  60.  
  61. % ---------------- Runtime support ---------------- %
  62.  
  63. /.packedfilefilter where
  64.  { pop }
  65.  { (gs_pfile.ps) run }
  66. ifelse
  67.  
  68. % ------ Output utilities ------ %
  69.  
  70. % By convention, the output file is named psfile.
  71.  
  72. % Define some utilities for writing the output file.
  73.    /wtstring 2000 string def
  74.    /wb {psfile exch write} bind def
  75.    /wnb {/wb load repeat} bind def
  76.    /w1 {psfile exch write} bind def
  77.    /ws {psfile exch writestring} bind def
  78.    /wl {ws (\n) ws} bind def
  79.    /wt {wtstring cvs ws ( ) ws} bind def
  80.    /wd        % Write a dictionary.
  81.     { dup length wo {dict dup begin} wol { we } forall
  82.       {end} wol
  83.     } bind def
  84.    /wld        % Write a large dictionary more efficiently.
  85.            % Ignore the readonly attributes.
  86.     { dup length wo {dict dup begin} wol
  87.       0 exch
  88.        { exch wo wo () wl
  89.      1 add dup 200 eq
  90.       { wo ({def} repeat) wl 0 }
  91.      if
  92.        }
  93.       forall
  94.       dup 0 ne
  95.        { wo ({def} repeat) wl }
  96.        { pop }
  97.       ifelse
  98.       (end) ws
  99.     } bind def
  100.    /we        % Write a dictionary entry.
  101.     { exch wo wo /def cvx wo (\n) ws
  102.     } bind def
  103.    /wcs        % Write a CharString (or Subrs entry)
  104.     { dup type /stringtype eq
  105.        { 4330 exch changelenIV 0 ge
  106.           {    % Add some leading garbage bytes.
  107.         wtstring changelenIV 2 index length getinterval
  108.         .type1decrypt exch pop
  109.         wtstring exch 0 exch length changelenIV add getinterval
  110.       }
  111.       {    % Drop some leading garbage bytes.
  112.         wtstring .type1decrypt exch pop
  113.         changelenIV neg 1 index length 1 index sub getinterval
  114.       }
  115.      ifelse
  116.          binary_tokens encrypt_CharStrings and
  117.       { % Suppress recognizing the readonly status of the string.
  118.         4330 exch dup .type1encrypt exch pop wo
  119.       }
  120.       { encrypt_CharStrings
  121.          { 4330 exch dup .type1encrypt exch pop
  122.          } if
  123.         smallest_output
  124.          { wo
  125.          }
  126.          { readonly dup length wo
  127.            binary_tokens not { ( ) ws } if
  128.            readproc ws wx
  129.          }
  130.         ifelse
  131.       }
  132.      ifelse
  133.        }
  134.        { wo        % PostScript procedure
  135.        }
  136.       ifelse
  137.     } bind def
  138.  
  139. % Construct the inversion of the system name table.
  140.    /SystemNames where
  141.     { pop /snit 256 dict def
  142.       0 1 255
  143.        { dup SystemNames exch get
  144.          dup null ne { exch snit 3 1 roll put } { pop pop } ifelse
  145.        }
  146.       for
  147.     }
  148.     { /snit 1 dict def
  149.     }
  150.    ifelse
  151.  
  152. % Write an object, using binary tokens if requested and possible.
  153.    /woa        % write in ascii
  154.     { psfile exch write==only
  155.     } bind def
  156.  
  157.             % Lookup table for ASCII output.
  158.  
  159.    /intbytes    % int nbytes -> byte*
  160.     { { dup 255 and exch -8 bitshift } repeat pop
  161.     } bind def
  162.    /wotta 10 dict dup begin
  163.       { /booleantype /integertype }
  164.       { { ( ) ws woa } def }
  165.      forall
  166.         % Iterate over arrays so we can print operators.
  167.      /arraytype
  168.       { dup xcheck {(}) ({)} {(]) ([)} ifelse ws exch dup wol exch ws wop
  169.       } bind def
  170.      /dicttype
  171.       { ( ) ws wd } def
  172.      /nametype
  173.       { dup xcheck { ( ) ws } if woa
  174.       } bind def
  175.         % Map back operators to their names,
  176.         % so we can write procedures.
  177.      /nulltype
  178.       { pop ( null) ws
  179.       } bind def
  180.      /operatortype
  181.       { wtstring cvs cvn cvx wo
  182.       } bind def
  183.         % Convert reals to integers if possible.
  184.      /realtype
  185.       { dup cvi 1 index eq { cvi wo } { ( ) ws woa } ifelse
  186.       } bind def
  187.         % == truncates strings longer than 200 characters!
  188.      /stringtype
  189.       { (\() ws dup
  190.      { dup dup 32 lt exch 127 ge or
  191.         { (\\) ws dup -6 bitshift 48 add w1
  192.           dup -3 bitshift 7 and 48 add w1
  193.           7 and 48 add
  194.         }
  195.         { dup dup -2 and 40 eq exch 92 eq or {(\\) ws} if
  196.         }
  197.        ifelse w1
  198.      }
  199.     forall
  200.     (\)) ws wop
  201.       } bind def
  202.      /packedarraytype
  203.       { ([) ws dup { wo } forall
  204.     encodingnames 1 index known
  205.         % This is an encoding, but not one of the standard ones.
  206.         % Use the built-in encoding only if it is available.
  207.      { encodingnames exch get wo
  208.        ({findencoding}stopped{pop) ws
  209.        (}{counttomark 1 add 1 roll cleartomark}ifelse)
  210.      }
  211.      { pop ()
  212.      }
  213.     ifelse
  214.     (/packedarray where{pop counttomark packedarray exch pop}{]readonly}ifelse) ws
  215.     wl
  216.       }
  217.      def
  218.    end def
  219.  
  220.             % Lookup table for binary output.
  221.  
  222.    /wottb 8 dict dup begin
  223.    wotta currentdict copy pop
  224.      /integertype
  225.       { dup dup 127 le exch -128 ge and
  226.          { 136 wb 255 and wb }
  227.      { dup dup 32767 le exch -32768 ge and
  228.         { 134 wb 2 intbytes wb wb }
  229.         { 132 wb 4 intbytes wb wb wb wb }
  230.        ifelse
  231.      }
  232.     ifelse
  233.       } bind def
  234.      /nametype
  235.       { dup snit exch known
  236.          { dup xcheck { 146 } { 145 } ifelse wb
  237.        snit exch get wb
  238.      }
  239.      { wotta /nametype get exec
  240.      }
  241.     ifelse
  242.       } bind def
  243.      /stringtype
  244.       { dup dup length dup 255 le { 142 2 } { 2 intbytes 143 3 } ifelse wnb
  245.     ws wop
  246.       } bind def
  247.    end def
  248.  
  249.    /wop        % Write object protection
  250.      { wcheck not { /readonly cvx wo } if
  251.      } bind def
  252.    /wo        % Write an object.
  253.      { dup type binary_tokens { wottb } { wotta } ifelse
  254.        exch get exec
  255.      } bind def
  256.    /wol        % Write a list of objects.
  257.      { { wo } forall
  258.      } bind def
  259.  
  260. % Write a hex string for Subrs or CharStrings.
  261.    /wx        % string ->
  262.     { binary_CharStrings
  263.        { ws
  264.        }
  265.        { % Some systems choke on very long lines, so
  266.      % we break up the hexstring into chunks of 50 characters.
  267.       { dup length 25 le {exit} if
  268.         dup 0 25 getinterval psfile exch writehexstring (\n) ws
  269.         dup length 25 sub 25 exch getinterval
  270.       } loop
  271.      psfile exch writehexstring
  272.        } ifelse
  273.     } bind def
  274.  
  275. % ------ CharString encryption utilities ------ %
  276.  
  277. /enc_dict 20 dict def
  278. 1 dict begin
  279. /bind { } def        % make sure we can print out the procedures
  280. enc_dict begin
  281.  
  282. (type1enc.ps) run
  283. enc_dict /.type1decrypt undef        % we don't need this
  284.  
  285. end end
  286.  
  287. enc_dict { 1 index where { pop pop pop } { def } ifelse } forall
  288.  
  289. % ------ Other utilities ------ %
  290.  
  291. % Test whether two values are equal (for default dictionary entries).
  292.    /valueeq        % <obj1> <obj2> valueeq <bool>
  293.     { 2 copy eq
  294.        { pop pop true }
  295.        {    % Special hack for comparing FontMatrix values
  296.      dup type /arraytype eq 2 index type /arraytype eq and
  297.       { dup length 2 index length eq
  298.          { true 0 1 3 index length 1 sub
  299.         {    % Stack: arr1 arr2 true index
  300.           3 index 1 index get 3 index 3 -1 roll get eq not
  301.            { pop false exit }
  302.           if
  303.         }
  304.            for 3 1 roll pop pop
  305.          }
  306.          { pop pop false
  307.          }
  308.         ifelse
  309.       }
  310.       { pop pop false
  311.       }
  312.      ifelse
  313.        }
  314.       ifelse
  315.     } bind def
  316.  
  317. % ------ The main program ------ %
  318.  
  319. % Define the dictionary of keys to skip because they are treated specially.
  320. /.fontskipkeys mark
  321.   /CharStrings dup
  322.   /Encoding dup
  323.   /FDepVector dup
  324.   /FID dup
  325.   /FontInfo dup
  326.   /Metrics dup
  327.   /Metrics2 dup
  328.   /Private dup
  329. .dicttomark def
  330. /.minfontskipkeys mark
  331.   .fontskipkeys { } forall
  332.   /FontName dup
  333.   /UniqueID dup
  334. .dicttomark def
  335. /.privateskipkeys mark
  336.   /ND dup
  337.   /NP dup
  338.   /RD dup
  339.   /Subrs dup
  340. .dicttomark def
  341. /.minprivateskipkeys mark
  342.   .privateskipkeys { } forall
  343.   /MinFeature dup
  344.   /Password dup
  345.   /UniqueID dup
  346. .dicttomark def
  347.  
  348. % Define the procedures for the Private dictionary.
  349. % These must be defined without `bind',
  350. % for the sake of the DISKFONTS feature.
  351. 4 dict begin
  352.  /-! {string currentfile exch readhexstring pop} def
  353.  /-| {string currentfile exch readstring pop} def
  354.  /|- {readonly def} def
  355.  /| {readonly put} def
  356. currentdict end /encrypted_procs exch def
  357. 4 dict begin
  358.  /-! {string currentfile exch readhexstring pop
  359.    4330 exch dup .type1encrypt exch pop} def
  360.  /-| {string currentfile exch readstring pop
  361.    4330 exch dup .type1encrypt exch pop} def
  362.  /|- {readonly def} def
  363.  /| {readonly put} def
  364. currentdict end /unencrypted_procs exch def
  365.  
  366. % Construct an inverse dictionary of encodings.
  367. /encodingnames mark
  368.  StandardEncoding /StandardEncoding
  369.  ISOLatin1Encoding /ISOLatin1Encoding
  370.  SymbolEncoding /SymbolEncoding
  371.  DingbatsEncoding /DingbatsEncoding
  372.  /resourceforall where
  373.   { pop (*) { cvn dup findencoding exch } 100 string /Encoding resourceforall }
  374.  if
  375. .dicttomark def
  376.  
  377. % Invert the standard encodings.
  378. .knownEncodings length 256 mul dict begin
  379.   0 .knownEncodings
  380.    {  { currentdict 1 index known { pop } { 1 index def } ifelse
  381.     1 add
  382.       }
  383.      forall
  384.    }
  385.   forall pop
  386. currentdict end /inverseencodings exch def
  387.  
  388. /writefont        % <psfile> writefont - (writes the current font)
  389.  { /psfile exch def
  390.    /Font currentfont def
  391.    /FontInfo Font /FontInfo .knownget not { 0 dict } if def
  392.    /FontType Font /FontType get def
  393.    /hasPrivate Font /Private known def
  394.    /Private hasPrivate { Font /Private get } { 0 dict } ifelse def
  395.    /readproc binary_CharStrings { (-| ) } { (-! ) } ifelse def
  396.    /privateprocs
  397.      encrypt_CharStrings binary_tokens not and
  398.       { encrypted_procs } { unencrypted_procs } ifelse
  399.      def
  400.    /addlenIV false def
  401.    /changelenIV use_lenIV 0 lt
  402.     { 0 }
  403.     { use_lenIV Private /lenIV .knownget not
  404.        { 4 /addlenIV use_lenIV 4 ne def } if sub }
  405.    ifelse def
  406.    /minimize
  407.      smallest_output
  408.      FontType 1 eq and
  409.      Font /UniqueID known and
  410.    def
  411.    (%!FontType) ws FontType wtstring cvs ws (-1.0: ) ws
  412.      currentfont /FontName get wt
  413.      FontInfo /version .knownget not { (001.001) } if wl
  414.    FontInfo /CreationDate .knownget { (%%Creation Date: ) ws wl } if
  415.    FontInfo /VMusage .knownget
  416.     { (%%VMusage: ) ws dup wt wtstring cvs wl }
  417.    if
  418.    (systemdict begin) wl
  419.  
  420. % If we're going to use eexec, create the filters now.
  421.    /realpsfile psfile def
  422.    eexec_encrypt
  423.     { /eexecfilter psfile binary_CharStrings not
  424.        { pop /bxstring 35 string def
  425.       { pop dup length 0 ne
  426.          { realpsfile exch writehexstring realpsfile (\n) writestring }
  427.          { pop }
  428.         ifelse bxstring
  429.       }
  430.      /NullEncode filter dup /hexfilter exch def
  431.        }
  432.       if 55665 /eexecEncode filter def
  433.     }
  434.    if
  435.  
  436. % Turn on binary tokens if relevant.
  437.    binary_tokens { (currentobjectformat 1 setobjectformat) wl } if
  438.  
  439. % If the file has a UniqueID, write out a check against loading it twice.
  440.    minimize
  441.     { Font /FontName get wo
  442.       Font /UniqueID get wo
  443.       Private length addlenIV { 1 add } if wo
  444.       Font length 1 add wo        % +1 for FontFile
  445.       ( .checkexistingfont) wl
  446.     }
  447.     { Font /UniqueID known
  448.        { ({} FontDirectory) ws Font /FontName get dup wo ( known) wl
  449.      ( {) ws wo ( findfont dup /UniqueID known) wl
  450.      (    { dup /UniqueID get) ws Font /UniqueID get wo ( eq exch /FontType get 1 eq and }) wl
  451.      (    { pop false } ifelse) wl
  452.      (    { pop save /restore load } if) wl
  453.      ( } if) wl
  454.        }
  455.       if
  456.     }
  457.    ifelse
  458.  
  459. % If we are writing unencrypted CharStrings for a standard environment,
  460. % write out the encryption procedures.
  461.    privateprocs unencrypted_procs eq standard_only and
  462.     { (systemdict /.type1encrypt known) wl
  463.       ( { save /restore load } { { } } ifelse) wl
  464.       (userdict begin) wl
  465.       enc_dict { we } forall
  466.       (end exec) wl
  467.     }
  468.    if
  469.  
  470. % Write out the creation of the font dictionary and FontInfo.
  471.    minimize not
  472.     { Font length 1 add wo {dict begin} wol        % +1 for FontFile
  473.     }
  474.    if
  475.    (/FontInfo ) ws FontInfo wd {readonly def} wol
  476.  
  477. % Write out the other fixed entries in the font dictionary.
  478.    Font begin
  479.    Font
  480.     { minimize
  481.        { .minfontskipkeys 2 index known
  482.       { pop pop
  483.       }
  484.       { //.compactfontdefault 2 index .knownget
  485.          { 1 index valueeq { pop pop } { we } ifelse }
  486.          { we }
  487.         ifelse
  488.       }
  489.      ifelse
  490.        }
  491.        { .fontskipkeys 2 index known { pop pop } { we } ifelse
  492.        }
  493.       ifelse
  494.     } forall
  495.    /Encoding
  496.    encodingnames Encoding known
  497.    name_all_Encodings
  498.    Encoding StandardEncoding eq or
  499.    Encoding ISOLatin1Encoding eq or and
  500.     { encodingnames Encoding get cvx }
  501.     { Encoding }
  502.    ifelse
  503.    dup /StandardEncoding cvx eq minimize and
  504.     { pop pop }
  505.     { we }
  506.    ifelse
  507.  
  508. % Write the FDepVector, if any.
  509.    Font /FDepVector .knownget
  510.     { {/FDepVector [} wol
  511.        { /FontName get wo {findfont} wol () wl } forall
  512.       {] readonly def} wol
  513.     }
  514.    if
  515.  
  516. % Write out the Metrics, if any.
  517.    Font /Metrics .knownget
  518.     { (/Metrics ) ws wld {readonly def} wol
  519.     }
  520.    if
  521.    Font /Metrics2 .knownget
  522.     { (/Metrics2 ) ws wld {readonly def} wol
  523.     }
  524.    if
  525.  
  526. % Start the eexec-encrypted section, if applicable.
  527.   eexec_encrypt
  528.    { {currentdict currentfile eexec} wol () wl
  529.      /psfile eexecfilter store
  530.      (\000\000\000\000) ws {begin} wol
  531.    }
  532.   if
  533.  
  534. % Create and initialize the Private dictionary, if any.
  535.    hasPrivate
  536. {
  537.    Private
  538.    minimize
  539.     { begin {Private dup begin}
  540.     }
  541.     {  dup length privateprocs length add dict copy begin
  542.        privateprocs { readonly def } forall
  543.        /Private wo
  544.        currentdict length 1 add wo {dict dup begin}
  545.     }
  546.    ifelse wol () wl
  547.    currentdict
  548.     { 1 index minimize { .minprivateskipkeys } { .privateskipkeys } ifelse
  549.       exch known
  550.        { pop pop }
  551.        { 1 index /lenIV eq use_lenIV 0 ge and { pop use_lenIV } if we }
  552.       ifelse
  553.     } forall
  554.    addlenIV { /lenIV use_lenIV we } if
  555. }
  556. if
  557.  
  558. % Write the Subrs entries, if any.
  559.    currentdict /Subrs known
  560.     { (/Subrs[) wl
  561.       Subrs
  562.        { dup null ne
  563.       { wcs minimize not { () wl } if }
  564.       { pop /null cvx wo }
  565.      ifelse
  566.        } forall
  567.       {] dup {readonly pop} forall readonly def} wol () wl
  568.     }
  569.    if
  570.  
  571. % Wrap up the Private dictionary.
  572.    hasPrivate
  573.     { end            % Private
  574.       minimize
  575.        { {end readonly pop} }    % Private
  576.        { {end readonly def} }    % Private in font
  577.       ifelse wol
  578.     }
  579.    if
  580.  
  581. % Write the CharStrings entries.
  582. % Detect identical (eq) entries, which bdftops produces.
  583.    currentdict /CharStrings known
  584. {
  585.    /CharStrings wo CharStrings length wo
  586.    minimize
  587.     { encrypt_CharStrings not wo ( .readCharStrings) wl
  588.       CharStrings length dict
  589.       CharStrings
  590.        { exch inverseencodings 1 index .knownget not { dup } if wo
  591.         % Stack: vdict value key
  592.      3 copy pop .knownget { wo pop pop } { 3 copy put pop wcs } ifelse
  593.        } forall
  594.     }
  595.     { {dict dup Private begin begin} wol () wl
  596.       CharStrings length dict
  597.       CharStrings
  598.        { 2 index 1 index known
  599.       { exch wo 1 index exch get wo {load def} wol () wl
  600.       }
  601.       { 2 index 1 index 3 index put
  602.         exch wo wcs ( |-) wl
  603.       }
  604.      ifelse
  605.        } forall
  606.       {end end} wol
  607.     }
  608.    ifelse
  609.    pop
  610.     { readonly def }    % CharStrings in font
  611.    wol
  612. }
  613. if
  614.  
  615. % Terminate the output.
  616.    end            % Font
  617.    eexec_encrypt
  618.     { {end mark currentfile closefile} wol () wl
  619.       eexecfilter dup flushfile closefile    % psfile is eexecfilter
  620.       binary_CharStrings not { hexfilter dup flushfile closefile } if
  621.       /psfile realpsfile store
  622.       8
  623.        { (0000000000000000000000000000000000000000000000000000000000000000)
  624.          wl
  625.        }
  626.       repeat {cleartomark} wol
  627.     }
  628.    if
  629.     { FontName currentdict end definefont pop
  630.     }
  631.    wol
  632.    Font /UniqueID known { /exec cvx wo } if
  633.    binary_tokens { /setobjectformat cvx wo } if
  634.    ( end) wl        % systemdict
  635.  
  636.  } bind def
  637.  
  638. % ------ Other utilities ------ %
  639.  
  640. % Prune garbage characters and OtherSubrs out of the current font,
  641. % if the relevant dictionaries are writable.
  642. /prunefont
  643.  { currentfont /CharStrings get wcheck
  644.     { currentfont /CharStrings get dup [ exch
  645.        { pop dup (S????00?) .stringmatch not { pop } if
  646.        } forall
  647.       ] { 2 copy undef pop } forall pop
  648.     }
  649.    if
  650.  } bind def
  651.  
  652. end            % wrfont_dict
  653.  
  654. /writefont { wrfont_dict begin writefont end } def
  655.